package com.comp6521.project01;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.List;

public class LiPhaseTwo {

	public static int inputBufferSize = 30000;
	
	public static int outputBufferSize = 100000;
	
	public static boolean finishFlag = false;
	
	public void merge(List<String> fileNameList, String outputFolder) {
		int[] outputBuffer = new int[outputBufferSize];
		int[][] inputBuffers = new int[fileNameList.size()][inputBufferSize];
		List<BufferedReader> readers = new ArrayList<BufferedReader>();
		try {
			for(int i=0;i<fileNameList.size();i++){
				BufferedReader reader = new BufferedReader(new FileReader(fileNameList.get(i)));
				readers.add(reader);
				String tempString = null;
				int line = 0;
				while ((tempString = readers.get(i).readLine()) != null) {
					inputBuffers[i][line] = Integer.parseInt(tempString);
					line++;
					if(line >= inputBufferSize){
						break;
					}
				}
			}
			
			//
			int[] pointers = new int[fileNameList.size()];
			
			int outputBufferIndex = 0;
			while(true){
				int min = findMin(inputBuffers,pointers, readers);
				outputBuffer[outputBufferIndex % outputBufferSize] = min;
				if(outputBufferIndex % outputBufferSize == outputBufferSize-1){
					outputData(outputBuffer, outputBufferSize, outputFolder+"/result.dat");
				}
				outputBufferIndex++;
				if(finishFlag){
					break;
				}
			}
			outputData(outputBuffer, outputBufferIndex%outputBufferSize, outputFolder+"/result.dat");
			
			for(int i=0;i<fileNameList.size();i++){
				readers.get(i).close();
			}
			System.out.println("------------------");
			
			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				for(int i=0;i<fileNameList.size();i++){
					if (readers.get(i) != null) {
						try {
							readers.get(i).close();
						} 
						catch (IOException e1) {
						}
		            }
				}
	        }
	}
	
	
	private int findMin(int[][] arrays, int[] pointers, List<BufferedReader> readers) throws IOException{
		int min = 0;
		int index = 0;
		for(int i=0;i<arrays.length;i++){
			if(arrays[i][pointers[i]]>0){
				min = arrays[i][pointers[i]];
				index = i;
				break;
			}
		}
		
		for(int i=index+1;i<arrays.length;i++){
			if(arrays[i][pointers[i]]<=0){
				continue;
			}
			if(arrays[i][pointers[i]] < min){
				min = arrays[i][pointers[i]];
				index = i;
			}
		}
		pointers[index] = pointers[index]+1;
		
		for(int i=0;i<pointers.length;i++){
			if(pointers[i]>=inputBufferSize){
				arrays[i] = new int[inputBufferSize];
				String tempString = null;
				int line = 0;
				while ((tempString = readers.get(i).readLine()) != null) {
					arrays[i][line] = Integer.parseInt(tempString);
					line++;
					if(line >= inputBufferSize){
						break;
					}
				}
				pointers[i]= 0;
			}
		}
		
		//update finishFlag
		if(!finishFlag){
			boolean flag = true;
			for(int i=0;i<arrays.length;i++){
				if(arrays[i][pointers[i]]>0){
					flag = false;
					break;
				}
			}
			finishFlag = flag;
		}
		return min;
	}
	
	
	private void outputData(int[] outputBuffer, int length, String outputFile) throws IOException{
		BufferedWriter output = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outputFile, true)));
		for(int i=0;i<length;i++){
			StringBuffer sb = new StringBuffer();
			sb.append(outputBuffer[i]);
			sb.append("\r\n");
			output.write(sb.toString());
		}
		output.close();
		outputBuffer = new int[outputBufferSize];
	}
	
	

}
